<?php
class ModuleStatistics
{

    /**
     * @var ModuleStatistics
     */
    private static $instance;

    /**
     * @var resource
     */
    private $handle;

    /**
     * array of log data, no keys
     *
     * @var array
     */
    private $buffer = array();

    /**
     * Get instance of ModuleStatistics.
     *
     * @return ModuleStatistics $instance
     */
    public static function get()
    {
        if (!self::$instance) {
            self::$instance = new ModuleStatistics();
        }
        return self::$instance;
    }

    /**
     * Initialize.
     */
    private function __construct()
    {
    }

    /**
     * Connect to the remote log server.
     *
     * @throws Exception connection error
     * @return void
     */
    private function connectLogServer()
    {
        try {
            $configs = SzConfig::get()->loadAppConfig('logger');
            $this->handle = fsockopen(
                $configs['LOG_HOST'],
                $configs['LOG_PORT'],
                $errno,
                $errmsg,
                $configs['CONN_TIMEOUT']
            );

            if (false !== $this->handle) {
                stream_set_blocking($this->handle, 0); // non-blocking
                stream_set_timeout($this->handle, $configs['SEND_TIMEOUT']);
            } else {
                SzLogger::get()->error('Statistics: Cannot connect to remote log server', array(
                    'no'  => $errno,
                    'msg' => $errmsg,
                ));
            }
        } catch(Exception $e) {
            SzLogger::get()->error('Statistics: Exception caught', array(
                'msg'   => $e->getMessage(),
                'code'  => $e->getCode(),
                'trace' => $e->getTraceAsString(),
            ));
        }
    }

    /**
     * Send log to remote server.
     *
     * @return void
     */
    public function sendLog()
    {
        if (!$this->buffer) {
            return; // no log to send
        }
        if (!$this->handle) {
            $this->connectLogServer();
        }
        if ($this->handle) {
            if(SzConfig::get()->loadAppConfig('logger', 'COMPRESS')) {
                $data = gzcompress(json_encode($this->buffer));
            } else {
                $data = json_encode($this->buffer);
            }
            fwrite($this->handle, $data . "\r\n");
            fclose($this->handle);
            $this->buffer = array();
        }
    }

    /**
     * Save log into buffer
     *
     * @param string $platformId
     * @param int $cash
     * @param int $gold
     * @param int $level
     * @param int $rtime
     * @param string $session
     * @param string $act
     * @param string $tid default ''
     * @param string $item default ''
     * @param int $value default 0
     * @param int $value2 default 0
     * @param int $areaId default null, 分服id
     * @param int $gameId default null, 游戏id
     * @return void
     */
    public function saveLog($platformId, $cash, $gold, $level, $rtime, $session, $act, $tid = '', $item = '', $value = 0, $value2 = 0, $areaId = null, $gameId = null)
    {
        if (is_null($gameId)) {
            $appConfig = SzConfig::get()->loadAppConfig('app');
            $gameId = $appConfig['GAME_ID'];
        }

        $log = array(
            'game_id'   => $gameId,
            'uid'       => $platformId,
            'cash'      => $cash,
            'coin'      => $gold,
            'level'     => $level,
            'rtime'     => SzTime::setTime($rtime),
            'act'       => $act,
            'tid'       => $tid,
            'item'      => $item,
            'value'     => $value,
            'value2'    => $value2,
            'time'      => SzTime::setTime(),
            'token'     => $session,
            'ip'        => SzUtility::getClientHost(),
        );
        if (!is_null($areaId)) {
            $log['area_id'] = $areaId;
        }

        SzLogger::get()->notice(json_encode($log), array('channel' => SzAbstractLogger::LOG_CHANNEL_BUSINESS));

        // just add into buffer, send later
        $this->buffer[] = array('type' => 'prolog', 'data' => $log);
    }

    /**
     * clear log buffer
     *
     * @return null
     */
    public function clearLogBuffer()
    {
        $this->buffer = array();
    }
}